package com.scholarship.common.config;

import com.scholarship.common.utils.CommonUtil;
import com.scholarship.common.utils.RedisUtil;
import com.scholarship.modules.backend.service.RewardTimeService;
import com.scholarship.modules.login.dto.LoginInfoDto;
import com.scholarship.modules.login.entity.RewardTime;
import com.scholarship.modules.login.entity.Role;
import com.scholarship.modules.login.entity.User;
import com.scholarship.modules.login.mapper.LRewardTimeMapper;
import com.scholarship.modules.login.mapper.LRoleMapper;
import com.scholarship.modules.login.mapper.LUserMapper;
import com.scholarship.modules.login.service.LoginService;
import lombok.SneakyThrows;
import org.apache.commons.codec.digest.Md5Crypt;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Date;
import java.util.List;

/**
 * 自定义UserRealm类
 * 继承AuthorizingRealm
 * 自定义我们自己的授权和认证方法
 * 访问特定于应用程序的安全性数据（用户，角色和权限）
 *
 * @param "21/3/10"
 * @author zjh
 */
public class UserRealm extends AuthorizingRealm {

    @Autowired
    private LUserMapper lUserMapper;

    @Autowired
    private RewardTimeService rewardTimeService;


    /**
     * 管理员、学生、教师、学生申请状态、学生申述状态
     */
    private static final String[] roles = new String[]{"admin","student","teacher","submit","appeal"};

    //授权
    @SneakyThrows
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("执行=>授权doGetAuthorizationInfo()");

        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

        //获取当前用户信息
        Subject subject = SecurityUtils.getSubject();
        LoginInfoDto user = (LoginInfoDto) subject.getPrincipal();
        int roleNum = user.getRole();

        //查询当前用户身份为学生
        if(roleNum == 1) {
            RewardTime rewardTime = rewardTimeService.getRewardTime();//用redis读取数据
            Long nowTime = System.currentTimeMillis();//获取系统时间
            //如果时间为null,默认学生权限为1
            if(rewardTime.getSubmitEndTime() == null || rewardTime.getSubmitStartTime() == null
                    || rewardTime.getAppealEndTime() == null || rewardTime.getAppealStartTime() == null){
                roleNum = 1;
            }else if(nowTime > rewardTime.getSubmitStartTime().getTime()
                    && nowTime < rewardTime.getSubmitEndTime().getTime() +86399999) {//加 86399999（23小时59分59秒999毫秒）
                roleNum = 3;
            }else if(nowTime > rewardTime.getAppealStartTime().getTime()
                    && nowTime < rewardTime.getAppealEndTime().getTime() +86399999) {//加 86399999（23小时59分59秒999毫秒）
                roleNum = 4;
            }
        }

        //赋予用户身份
        info.addRole(roles[roleNum]);

        return info;
    }

    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println("执行=>认证doGetAuthenticationInfo()");

        UsernamePasswordToken userToken = (UsernamePasswordToken) authenticationToken;

        //连接真实数据库
        User user = lUserMapper.getUserByUserId(userToken.getUsername());
        //判断用户名是否存在或者账号被冻结
        if(user == null || user.getState().equals(0)) {
            throw new UnknownAccountException("用户名不存在或被冻结");
        }

        //认证实体信息
        Object principal = lUserMapper.getLoginInfoDtoByUserId(user.getUserId());
        //从数据库中获取密码
        Object credentials = user.getPassword();
        //当前realm名称
        String realmName = this.getName();

        return new SimpleAuthenticationInfo(principal,credentials, ByteSource.Util.bytes(user.getUserId()),realmName);
    }
}
